﻿using NetTopologySuite.Algorithm.Match;
using NetTopologySuite.Geometries;
using NetTopologySuite.Geometries.Utilities;
using NetTopologySuite.IO;
using NetTopologySuite.Operation.Valid;
using NUnit.Framework;

namespace NetTopologySuite.Samples.Tests.Github
{
    public class Issue467
    {
        [Test, Description("Exception thrown when doing Overlap on weird MultiPolygon"), Category("GitHub Issue #467")]
        public void TestWeirdPolygonOverlaps()
        {
            var reader = new WKTReader();
            var point = new Point(14.436641302074806, 46.152664043249864);
            var weirdMultipolygon = reader.Read(@"MULTIPOLYGON (
((14.4339828 46.1531875, 14.4339638 46.153288800000006, 14.4340434 46.153408600000006, 
    14.4344242 46.1534977, 14.434769300000001 46.1534538, 14.434982900000001 46.153437600000004, 
    14.4351181 46.153387, 14.4351988 46.1533894, 14.435310800000002 46.153381100000004, 
    14.4354583 46.153404900000005, 14.4357 46.153395100000004, 14.4358213 46.1533117, 
    14.435957700000001 46.153234100000006, 14.436522600000002 46.1529219, 14.4367783 46.152714700000004, 
    14.437007900000001 46.1525638, 14.437267 46.1524513, 14.4373751 46.1523881, 
    14.4374035 46.152350500000004, 14.437399500000001 46.152310400000005, 14.4373728 46.152270300000005, 
    14.437467300000002 46.1522099, 14.437569300000002 46.152289, 14.4386974 46.1530106, 
    14.439418400000001 46.153347800000006, 14.440187600000002 46.153683400000006, 14.4401726 46.153703900000004, 
    14.440494900000001 46.153834200000006, 14.4405107 46.1538176, 14.441133700000002 46.154087700000005, 
    14.4415937 46.1542363, 14.441952800000001 46.154324800000005, 14.442209900000002 46.1543821, 
    14.442399000000002 46.154365500000004, 14.442551600000002 46.1543222, 14.442715000000002 46.154221500000006, 
    14.442780500000001 46.1541529, 14.4428213 46.154065700000004, 14.4428365 46.153967200000004, 
    14.442826 46.153854800000005, 14.442651900000001 46.1535689, 14.4425304 46.1533801, 
    14.442478500000002 46.153212200000006, 14.442479500000001 46.153058, 14.4425574 46.152778700000006, 
    14.4426371 46.152497000000004, 14.442915300000001 46.1518487, 14.443142600000002 46.151448300000006, 
    14.4436657 46.1506266, 14.4438697 46.1503127, 14.444000500000001 46.150151400000006, 
    14.444173300000001 46.150042600000006, 14.4443607 46.149981600000004, 14.444567500000002 46.1499444, 
    14.445336800000002 46.1499473, 14.445627000000002 46.149955600000006, 14.4457953 46.1499661, 
    14.445998900000001 46.1500013, 14.4460837 46.150012100000005, 14.446171300000001 46.1500077, 
    14.4462436 46.1499952, 14.4463074 46.149981600000004, 14.446402200000001 46.149934200000004, 
    14.4467049 46.1497067, 14.447263900000001 46.149275100000004, 14.448217900000001 46.148524, 
    14.448412900000001 46.148330200000004, 14.448585900000001 46.1480885, 14.448883100000002 46.1475354, 
    14.448523600000001 46.1472502, 14.4483288 46.1471152, 14.448225 46.1470144, 
    14.4481137 46.147063800000005, 14.4479263 46.1471281, 14.4475753 46.1472265, 
    14.447544200000001 46.1472458, 14.447290200000001 46.147287000000006, 14.447175000000001 46.147294300000006, 
    14.447003700000002 46.147295400000004, 14.4469139 46.147291, 14.446652700000001 46.147303400000006, 
    14.446551600000001 46.1473127, 14.446136000000001 46.1473166, 14.446079800000001 46.1473202, 
    14.446017900000001 46.1473394, 14.4459443 46.1473956, 14.4458593 46.147477200000004, 
    14.445736900000002 46.147623100000004, 14.445626200000001 46.147764800000004, 14.4454785 46.147933900000005, 
    14.445352600000001 46.148087800000006, 14.445152 46.148293300000006, 14.4450897 46.1483496, 
    14.445047400000002 46.148372800000004, 14.4447959 46.148531600000005, 14.444652000000001 46.148609, 
    14.4444683 46.148729100000004, 14.444135000000001 46.1489284, 14.443979400000002 46.149042800000004, 
    14.443939700000001 46.1490797, 14.4438373 46.1492158, 14.4435085 46.1495284, 
    14.4433281 46.149603600000006, 14.4432884 46.1496366, 14.443245600000001 46.149702700000006, 
    14.4431864 46.149733600000005, 14.443152600000001 46.1497432, 14.443107500000002 46.1497625, 
    14.4430653 46.149770100000005, 14.443028600000002 46.149789500000004, 14.443002700000001 46.1498518, 
    14.442980100000002 46.1498653, 14.442943600000001 46.149861200000004, 14.4429186 46.1498416, 
    14.4429051 46.149785, 14.442940900000002 46.149734, 14.4428782 46.1496815, 
    14.442812300000002 46.1496032, 14.442864900000002 46.149498, 14.442873200000001 46.1492767, 
    14.442783100000002 46.149187700000006, 14.442922000000001 46.148943900000006, 14.443127800000001 46.148683500000004, 
    14.442989 46.148579700000006, 14.4426725 46.1484108, 14.442645500000001 46.1483902, 
    14.4425296 46.1483196, 14.442456600000002 46.148332800000006, 14.442335700000001 46.148344, 
    14.4422288 46.148364900000004, 14.442062700000001 46.148409, 14.4419698 46.148439800000006, 
    14.4417887 46.1484844, 14.4416042 46.1485922, 14.441422800000002 46.148716500000006, 
    14.441218200000002 46.1489315, 14.4410713 46.149046000000006, 14.4409542 46.1491047, 
    14.4405616 46.149253800000004, 14.440293100000002 46.149322600000005, 14.440127100000002 46.149338900000004, 
    14.439948000000001 46.1493635, 14.439785800000001 46.149369, 14.4397122 46.149368100000004, 
    14.4396193 46.1493557, 14.439384800000001 46.149385800000005, 14.439052 46.1494895, 
    14.438935200000001 46.1495169, 14.438781100000002 46.1496221, 14.438736200000001 46.149692, 
    14.438693200000001 46.1497338, 14.438601400000001 46.149807700000004, 14.438438300000001 46.149903900000005, 
    14.4382484 46.149975000000005, 14.4381395 46.1500527, 14.4378568 46.150218800000005, 
    14.4376633 46.1504087, 14.437555900000001 46.150488800000005, 14.437429400000001 46.1506021, 
    14.437375600000001 46.1505981, 14.4373149 46.150613400000005, 14.4372564 46.150638, 
    14.437208900000002 46.150676700000005, 14.437179200000001 46.150729600000005, 14.4371094 46.1507658, 
    14.437100000000001 46.1507993, 14.4370527 46.1508224, 14.4370255 46.1508534, 
    14.4370229 46.1508939, 14.436627900000001 46.1511876, 14.436511600000001 46.1512553, 
    14.436389400000001 46.1512782, 14.436272500000001 46.151273700000004, 14.436114700000001 46.1512046, 
    14.4360374 46.151178800000004, 14.435941600000001 46.1511998, 14.435560200000001 46.1513952, 
    14.4354396 46.151509700000005, 14.4352768 46.1516243, 14.4352151 46.1517579, 
    14.435180500000001 46.1517963, 14.4350523 46.151873200000004, 14.435001000000002 46.1519355, 
    14.434919 46.151985800000006, 14.4348206 46.1520583, 14.434397700000002 46.1522841, 
    14.434253100000001 46.1524104, 14.434171200000002 46.1524471, 14.433937 46.1525377, 
    14.433781900000001 46.152585800000004, 14.4337139 46.152640100000006, 14.433716200000001 46.1526791, 
    14.4336686 46.152672300000006, 14.433621100000002 46.1526702, 14.433637200000001 46.1527119, 
    14.433701500000002 46.152717200000005, 14.433753600000001 46.1527572, 14.4338013 46.1528519, 
    14.433802900000002 46.1529455, 14.433817900000001 46.152973900000006, 14.433918400000001 46.1530928, 
    14.433961900000002 46.1531377, 14.4339828 46.1531875), 
    (14.4399359 46.1497936, 14.439883300000002 46.149801000000004, 14.4396012 46.1499071, 
        14.439490900000001 46.149971400000005, 14.439395200000002 46.1499862, 14.439327700000002 46.149970200000006, 
        14.439051500000001 46.150070400000004, 14.438846300000002 46.1501524, 14.4386995 46.150200600000005, 
        14.438623300000001 46.150236, 14.438541500000001 46.150297300000005, 14.4385469 46.150316800000006, 
        14.438633300000001 46.1502969, 14.4386668 46.1503127, 14.4386764 46.150372000000004, 
        14.438763300000002 46.1503323, 14.438963600000001 46.1502539, 14.439182700000002 46.150157, 
        14.439363400000001 46.150077800000005, 14.439442600000001 46.150027400000006, 14.439713300000001 46.1499164, 
        14.439900000000002 46.1498472, 14.439947400000001 46.149816300000005, 14.4399359 46.1497936), 
    (14.437723400000001 46.1511093, 14.437710800000001 46.151116900000005, 14.4377226 46.1511608, 
        14.4376417 46.151205700000006, 14.4375262 46.1512557, 14.437503000000001 46.151282200000004, 
        14.4375716 46.1513198, 14.437746 46.151382500000004, 14.437723400000001 46.1511093), 
    (14.441487 46.1496581, 14.441049600000001 46.1496457, 14.4408367 46.1496415, 
        14.440460000000002 46.1496599, 14.440289600000002 46.14967, 14.4400943 46.149694000000004, 
        14.4399265 46.149775000000005, 14.4399359 46.1497936, 14.439947400000001 46.149816300000005, 
        14.439900000000002 46.1498472, 14.439713300000001 46.1499164, 14.439442600000001 46.150027400000006, 
        14.439363400000001 46.150077800000005, 14.439182700000002 46.150157, 14.438963600000001 46.1502539, 
        14.438763300000002 46.1503323, 14.4386764 46.150372000000004, 14.4383447 46.150718600000005, 
        14.438307300000002 46.150771600000006, 14.438193400000001 46.150828000000004, 14.437723400000001 46.1511093, 
        14.437746 46.151382500000004, 14.437865500000001 46.151433100000006, 14.438002500000001 46.151529700000005, 
        14.4380749 46.1515727, 14.4382204 46.151584, 14.4383029 46.1516001, 
        14.438353900000001 46.151560700000005, 14.4384507 46.151501800000005, 14.438651700000001 46.151404500000005, 
        14.438736700000002 46.151332700000005, 14.438810900000002 46.151227600000006, 14.438872900000002 46.151202500000004, 
        14.438991300000001 46.1511718, 14.439197700000001 46.151045800000006, 14.4393846 46.150912000000005, 
        14.4395211 46.150777600000005, 14.439562500000001 46.1507517, 14.4396474 46.1506144, 
        14.439783400000001 46.150521100000006, 14.4398332 46.1504746, 14.439932200000001 46.150434600000004, 
        14.4402436 46.1503029, 14.440323200000002 46.1502114, 14.4403082 46.150187900000006, 
        14.440374400000001 46.1501455, 14.440437300000001 46.1501302, 14.440709600000002 46.1500727, 
        14.4408334 46.150059600000006, 14.440937900000002 46.150015200000006, 14.4411465 46.149885000000005, 
        14.441279000000002 46.1497821, 14.441487 46.1496581), 
    (14.4417065 46.1495107, 14.4416696 46.1495456, 14.441614000000001 46.1495784, 
        14.441519600000001 46.149619, 14.441487 46.1496581, 14.441279000000002 46.1497821, 
        14.4411465 46.149885000000005, 14.440937900000002 46.150015200000006, 14.4408334 46.150059600000006, 
        14.440709600000002 46.1500727, 14.440437300000001 46.1501302, 14.440374400000001 46.1501455, 
        14.4403082 46.150187900000006, 14.440323200000002 46.1502114, 14.4402436 46.1503029, 
        14.439932200000001 46.150434600000004, 14.4398332 46.1504746, 14.439783400000001 46.150521100000006, 
        14.4396474 46.1506144, 14.439562500000001 46.1507517, 14.4395211 46.150777600000005, 
        14.4393846 46.150912000000005, 14.439197700000001 46.151045800000006, 14.438991300000001 46.1511718, 
        14.438872900000002 46.151202500000004, 14.438810900000002 46.151227600000006, 14.438736700000002 46.151332700000005, 
        14.438651700000001 46.151404500000005, 14.4384507 46.151501800000005, 14.438353900000001 46.151560700000005, 
        14.4383029 46.1516001, 14.438316700000001 46.151619700000005, 14.438438000000001 46.1517397, 
        14.4385007 46.1518785, 14.438677700000001 46.1520473, 14.438816000000001 46.1521066, 
        14.438872400000001 46.152087300000005, 14.438948000000002 46.151999800000006, 14.439005100000001 46.151920000000004, 
        14.4390531 46.151862400000006, 14.439048900000001 46.1518164, 14.4390836 46.151778500000006, 
        14.439171100000001 46.1517059, 14.439232800000001 46.1516983, 14.439255800000002 46.1516777, 
        14.4392358 46.1516285, 14.439247400000001 46.1516031, 14.4394375 46.151548500000004, 
        14.439531500000001 46.1515046, 14.439669400000001 46.151419600000004, 14.439690500000001 46.1513657, 
        14.4397181 46.151338900000006, 14.439752400000001 46.151332700000005, 14.439811800000001 46.151329800000006, 
        14.439839300000001 46.151322, 14.439872000000001 46.151246, 14.439922600000001 46.1512113, 
        14.440085300000002 46.151155, 14.4400992 46.1511361, 14.440095000000001 46.1510964, 
        14.4401226 46.1510711, 14.440203 46.1510255, 14.440706500000001 46.1507834, 
        14.4410983 46.1506301, 14.4413526 46.1505239, 14.4414279 46.150506400000005, 
        14.441477500000001 46.1504902, 14.4415548 46.1504847, 14.441587100000001 46.1504744, 
        14.4416302 46.1504537, 14.4417691 46.150427, 14.4419278 46.1504016, 
        14.4421811 46.150332500000005, 14.4422215 46.1502927, 14.442168400000002 46.150257700000004, 
        14.4421014 46.150180600000006, 14.442105900000001 46.1500938, 14.442135200000001 46.150012200000006, 
        14.4421063 46.1499449, 14.4420728 46.1499437, 14.442005600000002 46.1499219, 
        14.441933 46.1498786, 14.4418327 46.149802, 14.4418135 46.1497649, 
        14.441803100000001 46.149675, 14.441818000000001 46.1495912, 14.441869500000001 46.149474700000006, 
        14.4418403 46.1494761, 14.4417065 46.1495107)), 
((14.4426816 46.1597324, 14.4426728 46.159786700000005, 14.4426778 46.159937600000006, 
    14.4426471 46.1600928, 14.4426488 46.160171600000005, 14.442702500000001 46.1602132, 
    14.442725900000001 46.1603055, 14.442762900000002 46.1603921, 14.442880700000002 46.160384400000005, 
    14.443374 46.160303400000004, 14.443548400000001 46.160095000000005, 14.4436318 46.1597981, 
    14.443667300000001 46.159687600000005, 14.443692500000001 46.159617000000004, 14.4437967 46.1595657, 
    14.4438458 46.1595121, 14.4438338 46.1594173, 14.4441106 46.1592113, 
    14.4441956 46.159160400000005, 14.444529800000002 46.1590154, 14.4447959 46.158920800000004, 
    14.444912200000001 46.1589176, 14.4450155 46.158867300000004, 14.445047500000001 46.1587814, 
    14.445527 46.158580300000004, 14.4458303 46.1585498, 14.446072200000001 46.158491500000004, 
    14.446358900000002 46.1584414, 14.4464973 46.1583951, 14.446144400000001 46.1579721, 
    14.446091200000001 46.1578816, 14.446111900000002 46.1577069, 14.4462314 46.1571209, 
    14.446263600000002 46.156874800000004, 14.446279400000002 46.156643700000004, 14.446277700000001 46.156545900000005, 
    14.446240300000001 46.1564987, 14.446280100000001 46.1563886, 14.4462638 46.1563518, 
    14.446335600000001 46.1559474, 14.4465198 46.155218500000004, 14.446719000000002 46.154667200000006, 
    14.446893300000001 46.154217700000004, 14.4470171 46.1539544, 14.447038500000001 46.153922400000006, 
    14.4475818 46.1529916, 14.4478807 46.1525106, 14.448260300000001 46.1519515, 
    14.448742600000001 46.151188600000005, 14.4489251 46.1509226, 14.449018200000001 46.1508236, 
    14.4490522 46.1507961, 14.4491425 46.150747800000005, 14.449398500000001 46.1506963, 
    14.4494716 46.150685, 14.449618000000001 46.1506447, 14.449705600000001 46.1506142, 
    14.450064200000002 46.1504052, 14.4501036 46.1503956, 14.4501854 46.150355000000005, 
    14.450405600000002 46.150274200000005, 14.450512300000002 46.1502418, 14.4505727 46.1502026, 
    14.450614600000002 46.150121600000006, 14.4508243 46.149982200000004, 14.4509161 46.149962900000006, 
    14.451005 46.149917200000004, 14.4510056 46.149855800000005, 14.450980900000001 46.149798600000004, 
    14.451025300000001 46.1497502, 14.4512254 46.1496731, 14.4512678 46.1496421, 
    14.4512906 46.149613, 14.4513365 46.149513600000006, 14.451416100000001 46.149412600000005, 
    14.451464300000001 46.149364000000006, 14.4515208 46.1493272, 14.451662 46.149245900000004, 
    14.4518231 46.1491355, 14.4519248 46.149071600000006, 14.451950400000001 46.1490366, 
    14.451976700000001 46.148937200000006, 14.4519996 46.148888500000005, 14.4520253 46.1488437, 
    14.452062300000001 46.148801000000006, 14.452107400000001 46.1487758, 14.4522089 46.1487392, 
    14.4522738 46.1487064, 14.4523191 46.148661700000005, 14.452438800000001 46.148484700000004, 
    14.4525561 46.1482667, 14.452602200000001 46.148140100000006, 14.452614700000002 46.1480133, 
    14.452601000000001 46.1479781, 14.452534600000002 46.147882200000005, 14.452521 46.1478334, 
    14.4525243 46.1477846, 14.452551000000001 46.1476423, 14.4525635 46.1475116, 
    14.452539400000001 46.1473905, 14.4525401 46.1473281, 14.452546000000002 46.1472969, 
    14.452376200000002 46.1469965, 14.452346200000001 46.146947600000004, 14.451617500000001 46.146817000000006, 
    14.451227600000001 46.146728700000004, 14.4510658 46.1471463, 14.450936800000001 46.1473534, 
    14.450821000000001 46.147471, 14.450705000000001 46.1476142, 14.4507332 46.147658400000005, 
    14.4506946 46.147701700000006, 14.450606800000001 46.147781300000005, 14.450569900000001 46.147824, 
    14.450521400000001 46.147899900000006, 14.4505011 46.147966200000006, 14.450494500000001 46.1480617, 
    14.4504712 46.148155300000006, 14.4504227 46.1482292, 14.450368800000001 46.1482855, 
    14.450348700000001 46.1483342, 14.450334000000002 46.1483927, 14.450330500000002 46.1484688, 
    14.4503383 46.1485332, 14.450340200000001 46.148621000000006, 14.4503284 46.1486815, 
    14.450302400000002 46.1487574, 14.450247500000001 46.1489094, 14.450099400000001 46.1491253, 
    14.4499863 46.149202800000005, 14.4499437 46.1492494, 14.4498136 46.1493483, 
    14.4496921 46.149419900000005, 14.449545700000002 46.149468000000006, 14.4494267 46.1494931, 
    14.4493573 46.149498300000005, 14.4492851 46.149486800000005, 14.4491668 46.149454500000004, 
    14.449107900000001 46.149450300000005, 14.4490628 46.1494657, 14.4489724 46.149525700000005, 
    14.4483955 46.1497751, 14.4483437 46.1497862, 14.4481978 46.149784100000005, 
    14.4481385 46.149804700000004, 14.447861900000001 46.1499536, 14.447833300000001 46.150004200000005, 
    14.447809500000002 46.1501426, 14.447789100000001 46.1502108, 14.4477437 46.150263300000006, 
    14.4476787 46.1503098, 14.447622200000001 46.150336900000006, 14.4475914 46.150336700000004, 
    14.447535400000001 46.150313000000004, 14.4471416 46.150452900000005, 14.446818200000001 46.1505245, 
    14.4469142 46.1505608, 14.4469904 46.1505967, 14.447003 46.150619600000006, 
    14.4470047 46.150654700000004, 14.4469992 46.150680200000004, 14.446976600000001 46.1507001, 
    14.4468554 46.150800100000005, 14.4466826 46.150941200000005, 14.446471500000001 46.1511695, 
    14.4463193 46.1512018, 14.446189400000002 46.151247700000006, 14.446079000000001 46.151367300000004, 
    14.446013500000001 46.1513481, 14.445574 46.1518542, 14.4455915 46.152287900000005, 
    14.445592000000001 46.152314700000005, 14.4456071 46.152839, 14.445615100000001 46.152891200000006, 
    14.445648100000001 46.1530459, 14.445658300000002 46.1530916, 14.4457097 46.1533214, 
    14.4456854 46.153486900000004, 14.445682900000001 46.1535042, 14.4456801 46.1535239, 
    14.445547600000001 46.1539811, 14.445393900000001 46.154462300000006, 14.445256100000002 46.154963200000005, 
    14.445229900000001 46.155615700000006, 14.4451847 46.155908800000006, 14.445136900000001 46.1560002, 
    14.445128500000001 46.1560162, 14.4451186 46.156035300000006, 14.4450949 46.1560828, 
    14.4449821 46.1562573, 14.4448077 46.156417100000006, 14.444770700000001 46.1564691, 
    14.444351800000002 46.1568708, 14.44424 46.1572442, 14.4441176 46.157488, 
    14.4440279 46.157632400000004, 14.443930100000001 46.157740700000005, 14.443804600000002 46.1577922, 
    14.4435704 46.157832400000004, 14.4433422 46.157836800000005, 14.442858600000001 46.1579502, 
    14.442698100000001 46.1579611, 14.442596700000001 46.158090300000005, 14.4425132 46.158328600000004, 
    14.4425041 46.1584188, 14.4426056 46.1585471, 14.4426321 46.1586112, 
    14.442593500000001 46.1586768, 14.4425737 46.158768800000004, 14.4426427 46.159167700000005, 
    14.4426035 46.159299100000005, 14.442604500000002 46.1594702, 14.4426904 46.1595803, 
    14.442697 46.159636000000006, 14.4426816 46.1597324))
)");
            Assert.That(weirdMultipolygon.IsValid, Is.False);
            double initialArea = weirdMultipolygon.Area;

            var isValidOp = new IsValidOp(weirdMultipolygon);
            if (!isValidOp.IsValid)
                TestContext.WriteLine(isValidOp.ValidationError);

            var fixedMultipolygon = GeometryFixer.Fix(weirdMultipolygon);
            Assert.That(fixedMultipolygon.IsValid, Is.True);

            double similarity = new HausdorffSimilarityMeasure().Measure(weirdMultipolygon, fixedMultipolygon);
            Assert.That(similarity, Is.EqualTo(1).Within(0.03));

            bool res = true;
            Assert.That(() => res = fixedMultipolygon.Intersects(point), Throws.Nothing);
            Assert.That(res, Is.True);

        }
    }
}
